package com.qianli.cashmama.trade.integration.user.impl;

import com.alibaba.fastjson.JSON;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.xjd.user.client.*;
import com.fqgj.xjd.user.client.enums.FrozenCodeEnum;
import com.fqgj.xjd.user.client.enums.UserCardStatusEnum;
import com.fqgj.xjd.user.client.enums.UserEventTrackEnum;
import com.fqgj.xjd.user.client.request.CopyUserRequest;
import com.fqgj.xjd.user.client.request.ShumeiDevice;
import com.fqgj.xjd.user.client.request.UserBank;
import com.fqgj.xjd.user.client.request.UserBehaviorEvent2Request;
import com.fqgj.xjd.user.client.response.*;
import com.google.common.collect.Lists;
import com.qianli.cashmama.trade.common.dto.UserTradeSnapshotDto;
import com.qianli.cashmama.trade.common.error.TradeErrorCodeEnum;
import com.qianli.cashmama.trade.common.exceptions.TradeException;
import com.qianli.cashmama.trade.integration.user.UserIntegrationService;
import com.qianli.cashmama.trade.integration.user.dto.UserBankDto;
import com.qianli.cashmama.trade.integration.user.dto.UserBaseInfoDto;
import com.qianli.cashmama.trade.integration.user.dto.UserContactAddressBookDto;
import com.qianli.cashmama.trade.integration.user.dto.UserLoginInfoDto;
import com.qianli.common.enums.BusinessTypeENUM;
import com.qianli.user.enums.UserAuthEnum;
import com.qianli.user.enums.UserAuthStatusEnum;
import com.qianli.user.facade.auth.UserAuthServiceFacade;
import com.qianli.user.ro.auth.UserAuthRO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2017/7/20
 * Time: 下午5:40
 */
@Service
public class UserIntegrationServiceImpl implements UserIntegrationService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserIntegrationServiceImpl.class);

    @Autowired
    private UserService userService;

    @Autowired
    private UserBankService userBankService;

    @Autowired
    private UserPanService userPanService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private UserDeviceService userDeviceService;

    @Autowired
    private UserQuotaService userQuotaService;

    @Autowired
    private UserAuthPictureService userAuthPictureService;

    @Autowired
    private UserContactService userContactService;

    @Autowired
    private UserBehaviorService userBehaviorService;

    @Autowired
    private UserKycDocumentService userKycDocumentService;

    @Autowired
    private UserAuthServiceFacade userAuthServiceFacade;

    @Override
    public User getUserByUserCode(String userCode) {
        try {
            return userService.getUserByUserCode(userCode).getData();
        } catch (Exception e) {
            LOGGER.error("== 获取用户失败 ==,userCode:{},e", userCode, e);
            return null;
        }
    }


    @Override
    public UserAccessInfo getUserAccessInfoByUserCode(String userCode) {
        return userService.getUserAccessInfoByUserCode(userCode).getData();
    }

    @Override
    public UserAccessInfo getUserAccessInfoByMobile(String mobile, String appCode) {
        return userService.getUserAccessInfoByMobile(mobile, appCode).getData();
    }

    @Override
    public UserBaseInfoDto getUserBaseInfoByUserCode(String userCode, String productCategory) {
        try {
            Response<User> userResponse = userService.getUserByUserCode(userCode);
            if (!userResponse.isSuccess() || userResponse.getData() == null) {
                LOGGER.error("== 获取用户基本信息失败 userResponse ==,userCode:{},productCategory:{}", userCode, productCategory);
                return null;
            }
            UserBaseInfoDto userBaseInfoDto = new UserBaseInfoDto();
            User user = userResponse.getData();
            if (user != null) {
                userBaseInfoDto
                        .setUserId(user.getId())
                        .setIdentityNo(user.getIdentityNo())
                        .setMobile(user.getMobile())
                        .setUserName(user.getName())
                        .setIdentityNo(user.getIdentityNo())
                        .setUserType(user.getUserType())
                        .setRegisterDate(user.getGmtCreate());
                //账号冷冻判断
                Integer frozenStatus = 0;
                List<UserFrozen> frozens = user.getFrozenList();
                List<String> fronzenCodes = Lists.newArrayList();
                List<String> productCategories = Lists.newArrayList();
                if (!CollectionUtils.isEmpty(user.getFrozenList())) {
                    frozenStatus = 1;
                    for (UserFrozen frozen : frozens) {
                        fronzenCodes.add(frozen.getCode());
                        productCategories.add(frozen.getCategoryCode());
                    }
                    if (!fronzenCodes.contains(FrozenCodeEnum.FROZEN.getCode())
                            && !fronzenCodes.contains(FrozenCodeEnum.FACE_RECONGNITION.getCode())
                            && !productCategories.contains(productCategory)) {
                        frozenStatus = 0;
                    }
                }
                userBaseInfoDto.setFrozenStatus(frozenStatus);
            }

            Response<UserInfo> userInfoResponse = userInfoService.getUserInfoByUserCode(userCode);
            if (!userInfoResponse.isSuccess() || userInfoResponse.getData() == null) {
                LOGGER.error("== 获取用户基本信息失败 userInfoResponse ==,userCode:{},productCategory:{}", userCode, productCategory);
                return null;
            }
            if (userInfoResponse.getData().getUserBase() != null) {
                userBaseInfoDto.setUserLanguage(userInfoResponse.getData().getUserBase().getUserLanguage());
                userBaseInfoDto.setBirthday(userInfoResponse.getData().getUserBase().getBirthday());
                userBaseInfoDto.setGender(userInfoResponse.getData().getUserBase().getGender());
            }
            if (userInfoResponse.getData().getUserResident() != null) {
                userBaseInfoDto.setCity(userInfoResponse.getData().getUserResident().getPermanentCity());
            }

            Response<UserQuotaResponse> userQuotaServiceQuota = userQuotaService.getQuota(userCode, productCategory);
            if (userQuotaServiceQuota == null) {
                LOGGER.info("== 获取用户基本信息失败 userQuotaServiceQuota==,userCode:{},productCategory:{}", userCode, productCategory);
                return null;
            }

            UserQuotaResponse userQuotaResponse = userQuotaServiceQuota.getData();
            if (userQuotaResponse != null) {
                Double userQuota = userQuotaResponse.getQuota();
                if (userQuota == null) {
                    userQuota = 0.0;
                }

                userBaseInfoDto.setUserQuota(new BigDecimal(userQuota));
            }
            return userBaseInfoDto;
        } catch (Exception e) {
            LOGGER.error("== 获取用户基本信息失败 ==,userCode:{},productCategory:{},e", userCode, productCategory, e);
            return null;
        }
    }


    @Override
    public UserContactAddressBookDto getUserDeviceContactByUserCode(String userCode) {
        Response<UserContactAddressBook> userDeviceContactByUserCode = userContactService.getUserDeviceContactByUserCode(userCode);
        UserContactAddressBook userContactAddressBook = Optional.ofNullable(userDeviceContactByUserCode).filter(Response::isSuccess).map(Response::getData).orElse(null);
        if (null == userContactAddressBook) {
            return null;
        } else {
            UserContactAddressBookDto userContactAddressBookDto = new UserContactAddressBookDto();
            BeanUtils.copyProperties(userContactAddressBook, userContactAddressBookDto);
            return userContactAddressBookDto;
        }
    }

    @Override
    public UserTradeSnapshotDto getUserTradeSnapshotInfoByUserCode(String userCode, String productCategory) {
        return this.getUserTradeSnapshotInfoByUserCode(userCode, productCategory, null);
    }

    /**
     * @param userCode
     * @param productCategory
     * @param noNeed
     * @return
     */
    @Override
    public UserTradeSnapshotDto getUserTradeSnapshotInfoByUserCode(String userCode, String productCategory, Set<String> noNeed) {
        try {
            UserSocialContact userSocialContact = userContactService.getUserSocialContactByUserCode(userCode).getData();
            if (userSocialContact == null) {
                throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + "userSocialContact==");
            }

            UserInfo userInfo = userInfoService.getUserInfoByUserCode(userCode).getData();
            if (userInfo == null) {
                throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + "userInfo==");
            }

            UserQuotaResponse userQuotaResponse = userQuotaService.getQuota(userCode, productCategory).getData();
            if (userQuotaResponse == null) {
                throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + " userQuotaResponse==");
            }

            UserBehaviorRegister userBehaviorRegister = userService.getRegisterInfo(userCode).getData();
            if (userBehaviorRegister == null) {
                throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + " userBehaviorRegister==");
            }

            List<UserAuthFaceRecognition> userAuthFaceRecognitionList = userAuthPictureService.getFaceRecognitionByUserCode(userCode).getData();
            if (userAuthFaceRecognitionList == null) {
                throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + "userAuthFaceRecognitionList==");
            }

            UserBankInfo userBankInfo = null;
            if (noNeed == null || !noNeed.contains("userBankInfo")) {
                userBankInfo = userBankService.getByUserCode(userCode).getData();
                if (userBankInfo == null) {
                    throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + " userBankInfo==");
                }
            }

            List<UserKycDocumentInfo> userKycDocumentInfos = userKycDocumentService.getByUserCode(userCode).getData();
            if (CollectionUtils.isEmpty(userKycDocumentInfos)) {
                throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + " UserKycDocumentInfo==");
            }

            UserPanInfo userPanInfo = userPanService.getByUserCode(userCode).getData();
            if (userPanInfo == null) {
                throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed, TradeErrorCodeEnum.fetch_user_snapshot_failed.getMsg() + " userPanInfo==");
            }

            UserGps userGps = userBehaviorService.getLatestUserGps(userCode).getData();
            if (userGps == null) {
                LOGGER.info("== 获取用户快照(gps)信息错误 ==,userCode:{},e", userCode);
            }

            ShumeiDevice shumeiDevice = null;
            try {
                shumeiDevice = userDeviceService.getShumeiDeviceByUserCode(userCode).getData();
                if (shumeiDevice == null) {
                    LOGGER.info("== 获取用户快照(shumeiDevice)信息错误，为null ==,userCode:{}", userCode);
                }
            } catch (Exception e) {
                LOGGER.error("== 获取用户快照(shumeiDevice)信息异常 ==,userCode:{}", userCode, e);
            }

            Map<String, String> wifiNameMapByUserCodes = new HashMap<>();
//            try {
//                List<String> userCodeList = userDeviceService.getDeviceRegisterUserCodesByCurrentUserCode(userCode).getData();
//                if (!CollectionUtils.isEmpty(userCodeList)) {
//                    wifiNameMapByUserCodes = userDeviceService.getUserLatestWifiNameMapByUserCodes(userCodeList).getData();
//                }
//            } catch (Exception e) {
//                LOGGER.warn("== 获取用户获取当前用户的最新的设备wifi map。结果为用户id和wifi名称的映射错误 ==,userCode:{}", userCode);
//            }

            return new UserTradeSnapshotDto()
                    .setUserSocialContact(userSocialContact)
                    .setUserInfo(userInfo)
                    .setUserQuotaResponse(userQuotaResponse)
                    .setUserBehaviorRegister(userBehaviorRegister)
                    .setUserauthFaceRecognitionList(userAuthFaceRecognitionList)
                    .setUserBankInfo(userBankInfo)
                    .setWifiMap(wifiNameMapByUserCodes)
                    .setUserPanInfo(userPanInfo)
                    .setShumeiDevice(shumeiDevice)
                    .setUserGps(userGps)
                    .setUserKycDocumentInfo(userKycDocumentInfos.get(0));

        } catch (TradeException e) {
            LOGGER.error("获取用户快照信息错误,userCode:" + userCode, e);
            throw e;
        } catch (Exception e) {
            LOGGER.error("获取用户快照信息异常,userCode:" + userCode, e);
            throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed);
        }
    }

    @Override
    public UserBankDto getUserBankSnapshotByUserCode(String userCode) {

        Response<UserBankInfo> bankInfoResponse = userBankService.getByUserCode(userCode);
        if (!bankInfoResponse.isSuccess()) {
            throw new TradeException(TradeErrorCodeEnum.default_error, "Bank card information is empty and transactions cannot be created");
        }

        UserBankInfo userBankInfo = bankInfoResponse.getData();
        if (userBankInfo == null || userBankInfo.getStatus() != 1) {
            throw new TradeException(TradeErrorCodeEnum.default_error, "The bank does not exist or is successfully bound");
        }

        return new UserBankDto()
                .setBankName(userBankInfo.getName())
                .setBankType(userBankInfo.getCode())
                .setCardNo(userBankInfo.getCardNo())
                .setSignMobile(userBankInfo.getMobile())
                .setBindType(userBankInfo.getType());
    }

    @Override
    public Boolean changeUserBankStatus(String userCode) {
        try {
            LOGGER.info("== 用户设置重绑卡 ==,userCode:{}", userCode);
            UserBank userBank = new UserBank();
            userBank.setUserCode(userCode)
                    .setUserCardStatusEnum(UserCardStatusEnum.CHECK_FAIL);
            Response<Boolean> response = userBankService.bind(userBank);
            LOGGER.info("== 用户设置重绑卡,返回信息 ==,userCode:{},response:{}", userCode, JSON.toJSONString(response));
            if (response.isSuccess()) {
                return response.getData();
            }
            return false;
        } catch (Exception e) {
            LOGGER.error("== 用户设置重绑卡失败 ==,userCode:{},e", userCode, e);
            return false;
        }
    }

    @Override
    public boolean frozenUser(String userCode, String productCategory, FrozenCodeEnum frozenCodeEnum) {
        try {
            Response<Boolean> response = userService.frozenUser(userCode, frozenCodeEnum, productCategory);
            return response == null ? false : response.getData();
        } catch (Exception e) {
            LOGGER.error("== 冷冻用户异常 ==,userCode:{},e", userCode, e);
            return false;
        }
    }

    @Override
    public String getUserWifiNameByUserCode(String userCode) {
        try {
            List<String> userCodes = new ArrayList<>();
            userCodes.add(userCode);
            Response<Map<String, String>> userLatestWifiNameMapByUserCodes = userDeviceService.getUserLatestWifiNameMapByUserCodes(userCodes);
            if (userLatestWifiNameMapByUserCodes == null || userLatestWifiNameMapByUserCodes.getData() == null || !userLatestWifiNameMapByUserCodes.isSuccess()) {
                return "暂无";
            }

            return userLatestWifiNameMapByUserCodes.getData().get(userCode);
        } catch (Exception e) {
            LOGGER.info("== 获取wifi异常 ==,userCode:{},e", userCode, e);
            return "";
        }
    }

    @Override
    public List<String> getLatestChannelFromRegister(Integer hour) {
        Response<List<String>> latestChannelFromRegister = userBehaviorService.getLatestChannelFromRegister(hour);
        if (latestChannelFromRegister.isSuccess() && latestChannelFromRegister.getData() != null) {
            return latestChannelFromRegister.getData();
        }
        return null;
    }

    /**
     * 获取用户登录基本信息
     */
    @Override
    public UserLoginInfoDto getUserLoginInfo(String userCode) {
        Response<UserLoginInfo> userLoginInfo = userService.getUserLoginInfo(userCode);
        return Optional.ofNullable(userLoginInfo)
                .filter(Response::isSuccess)
                .map(Response::getData)
                .map(data -> {
                    UserLoginInfoDto userLoginInfoDto = new UserLoginInfoDto();
                    BeanUtils.copyProperties(data, userLoginInfoDto);
                    return userLoginInfoDto;
                })
                .orElseThrow(() -> new TradeException(TradeErrorCodeEnum.default_error, "get user Login info error userCode::" + userCode));
    }

    /**
     * 重绑卡
     *
     * @param userCode
     * @param ifscCode
     * @param cardNumber
     * @param bankName
     * @return
     */
    @Override
    public boolean reBindCard(String userCode, String ifscCode, String cardNumber, String bankName) {
        UserBank userBank = new UserBank();
        userBank.setUserCode(userCode);
        userBank.setCode(ifscCode);
        userBank.setNumber(cardNumber);
        userBank.setName(bankName);
        userBank.setUserCardStatusEnum(UserCardStatusEnum.CHECK_SUCCESS);
        userBankService.bind(userBank);
        return true;
    }

    @Override
    public boolean updateUserAuthStatus(String userCode, UserAuthEnum userAuthEnum, UserAuthStatusEnum userAuthStatusEnum) {
        try {
            UserAuthRO userAuthRO = new UserAuthRO();
            userAuthRO.setAppCode("5");
            userAuthRO.setUserCode(userCode);
            userAuthRO.setBiz(BusinessTypeENUM.XJD.getCode());
            userAuthRO.setUserAuthEnum(userAuthEnum);
            userAuthRO.setUserAuthStatusEnum(userAuthStatusEnum);
            userAuthServiceFacade.updateUserAuthStatus(userAuthRO);
            LOGGER.info("updateUserAuthStatus pay success userCode:{}", userCode);
        } catch (Exception e) {
            LOGGER.error("updateUserAuthStatus失败,userCode:{},e:{}", userCode, e);
        }
        return true;
    }

    /**
     * 用户复制
     *
     * @param userCode
     * @param targetAppCode
     * @param originCategoryCode
     * @param targetCategoryCode
     * @return
     */
    @Override
    public String copyUser(String userCode, String targetAppCode, String originCategoryCode, String targetCategoryCode) {
        try {
            CopyUserRequest copyUserRequest = new CopyUserRequest();
            copyUserRequest.setUserCode(userCode);
            copyUserRequest.setTargetAppCode(targetAppCode);
            copyUserRequest.setOriginCategoryCode(originCategoryCode);
            copyUserRequest.setTargetCategoryCode(targetCategoryCode);
            Response<CopyUserVO> copyUserVOResponse = userService.copyUser(copyUserRequest);
            if (!copyUserVOResponse.isSuccess() || copyUserVOResponse.getData() == null) {
                return null;
            }
            return copyUserVOResponse.getData().getUserCode();
        } catch (Exception e) {
            LOGGER.error("用户复制失败,userCode:{},targetAppCode:{},originCategoryCode:{},targetCategoryCode:{}", userCode, targetAppCode, originCategoryCode, targetCategoryCode, e);
            return null;
        }
    }

    /**
     * 查询短信
     *
     * @param userCode
     * @return
     */
    @Override
    public UserContactSms getUserDeviceSmsByUserCode(String userCode) {
        Response<UserContactSms> response = userContactService.getUserDeviceSmsByUserCode(userCode);
        if (!response.isSuccess() || response.getData() == null) {
            return null;
        }
        return response.getData();
    }

    /**
     * 添加用户埋点
     *
     * @param userCode
     * @param userEventTrackEnum
     */
    @Override
    public void addUserEventTrack(String userCode, UserEventTrackEnum userEventTrackEnum) {
        if (StringUtils.isEmpty(userCode) || userEventTrackEnum == null) {
            return;
        }
        try {
            UserBehaviorEvent2Request userBehaviorEvent2Request = new UserBehaviorEvent2Request();
            userBehaviorEvent2Request.setUserCode(userCode);
            userBehaviorEvent2Request.setUserEventTrack(userEventTrackEnum);
            userBehaviorService.addUserEventTrack(userBehaviorEvent2Request);
        } catch (Exception e) {
            LOGGER.warn("埋点失败," + userCode + "," + userEventTrackEnum, e);
        }
    }
}
